﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using Collections.TreeCollections;
using System.Collections;
using Collections;
using System.Windows;

namespace TreeGraphicalControl
{
    public delegate TreeViewItemControl TreeItemConstructorWithObject(TreeObject treeObj);
    public delegate TreeViewItemControl TreeItemConstructorWithTree(TreeRoot treeRoot);
    public delegate ContextMenu ContextMenuGeneratorWithObject(TreeViewItemControl treeItem, TreeObject treeObj);
    public delegate ContextMenu ContextMenuGeneratorWithTree(TreeViewItemControl treeItem, TreeRoot treeRoot);
    public class ItemRegister
    {
        public Type ItemType { get; protected set; }
        public Type TreeObjectType { get; protected set; }
        public TreeItemConstructorWithObject Constructor { get; protected set; }
        public ContextMenuGeneratorWithObject MenuGenerator { get; protected set; }
        public ItemRegister(Type treeNodeType
            , Type treeItemType
            , TreeItemConstructorWithObject constructor
            , ContextMenuGeneratorWithObject menuGenerator)
        {
            ItemType = treeItemType;
            TreeObjectType = treeNodeType;
            Constructor = constructor;
            MenuGenerator = menuGenerator;
        }
    }

    public abstract class TreeViewItemGenerator
    {
        #region Properties
        public ItemRegister this[Type treeObjType] { get { return (ItemRegister)_registersList[treeObjType]; } }
        //public TreeItemConstructorWithTree Constructor { get { return _constructor; } }
        #endregion

        #region Fields
        /// <summary>
        /// key: Tree Object Type
        /// Value: ItemRegister
        /// </summary>
        protected Hashtable _registersList;
        protected TreeItemConstructorWithTree _constructor;
        protected ContextMenuGeneratorWithTree _contextMenuGenerator;

        #endregion

        public TreeViewItemGenerator(TreeItemConstructorWithTree constructor
            , ContextMenuGeneratorWithTree contextMenuGenerator)
        {
            _registersList = new Hashtable();

            _constructor = constructor;
            _contextMenuGenerator = contextMenuGenerator;


        }
        /// <summary>
        /// Register
        /// </summary>
        /// <param name="iRegister"></param>
        public void Register(ItemRegister iRegister)
        {
            _registersList.Add(iRegister.TreeObjectType
                , iRegister);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="treeObj"></param>
        /// <returns></returns>
        public TreeViewItemControl GenerateTreeItem(TreeObject treeObj, TreeViewItemControl[] orgItems)
        {
            ItemRegister iR = this[treeObj.GetType()];
            TreeViewItemControl control = iR.Constructor(treeObj);

            // valid control type
            if (control.GetType() != iR.ItemType)
            {
                throw new Exception("Register Item Type Error!");
            }

            control.Name = treeObj.ID.ToString();
            control.ContextMenu = iR.MenuGenerator(control, treeObj);

            TreeViewItemControl orgItem = getItems(orgItems, control.Name);
            if (orgItem != null)
            {
                control.IsExpanded = orgItem.IsExpanded;
            }
            return control;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="treeRoot"></param>
        /// <returns></returns>
        public TreeViewItemControl GenerateTreeItemRoot(TreeRoot treeRoot, TreeViewItemControl[] orgItems)
        {
            TreeViewItemControl control = _constructor(treeRoot);
            control.Focusable = true;
            control.Name = treeRoot.ID.ToString();

            control.ContextMenu = _contextMenuGenerator(control, treeRoot);

            TreeViewItemControl orgItem = getItems(orgItems, treeRoot.ID.ToString());
            if (orgItem != null)
            {
                control.IsExpanded = orgItem.IsExpanded;
            }

            return control;
        }
        /// <summary>
        /// Get items
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        protected TreeViewItemControl getItems(TreeViewItem[] items, string itemID)
        {
            if (items == null)
            {
                return null;
            }
            foreach (TreeViewItemControl item in items)
            {
                if (item == null)
                {
                    break;
                }
                if (item.Name == itemID)
                {
                    return item;
                }
            }
            return null;
        }
    }
}
